﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;
using System.Runtime.InteropServices;

namespace Mimoza.DateTimePlugin
{
    class TimeZoneData
    {
#if WindowsCE
        [DllImport("Mimoza.SetTimeZone.dll", CharSet = CharSet.Auto)]
        private static extern int SetTimeZone(string zone);
#endif

#if WindowsCE
        const string rootNodeName = @"Time Zones\";
#else
        const string rootNodeName = @"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\";
#endif

        public static byte[] Get(string timeZoneId)
        {

            byte[] timeZoneData = null;

            using (RegistryKey regKey = Registry.LocalMachine.OpenSubKey(rootNodeName + timeZoneId, false))
            {
                System.Text.UnicodeEncoding encoding = new System.Text.UnicodeEncoding();

                byte[] tziBytes = (byte[])regKey.GetValue("TZI");
                string timeZoneStdName = regKey.GetValue("Std").ToString();
                string timeZoneDltName = regKey.GetValue("Dlt").ToString();

                byte[] biasBytes = tziBytes.Skip(0).Take(4).ToArray();
                byte[] stdNameBytes = BuildStringBuffer(timeZoneStdName, 64);
                byte[] stdDateBytes = tziBytes.Skip(12).Take(16).ToArray();
                byte[] stdBiasBytes = new byte[4];

                byte[] dltNameBytes = BuildStringBuffer(timeZoneDltName, 64);
                byte[] dltDateBytes = tziBytes.Skip(28).Take(16).ToArray();
                byte[] dltBiasBytes = tziBytes.Skip(8).Take(4).ToArray();


                timeZoneData = ConcatArrays(biasBytes, stdNameBytes, stdDateBytes, stdBiasBytes,
                    dltNameBytes, dltDateBytes, dltBiasBytes);
            }

            return timeZoneData;
        }

        public static void Set(byte[] timeZoneData)
        {
#if WindowsCE
            //using (RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"\Time", true))
            //{
            //    regKey.SetValue("TimeZoneInformation", timeZoneData, RegistryValueKind.Binary);
            //    regKey.Flush();
            //}
#endif
        }
        public static void Set(string timeZoneId)
        {
#if WindowsCE
            SetTimeZone(rootNodeName + timeZoneId);
#endif
        }

        static T[] ConcatArrays<T>(params T[][] list)
        {
            var result = new T[list.Sum(a => a.Length)];
            int offset = 0;
            for (int x = 0; x < list.Length; x++)
            {
                list[x].CopyTo(result, offset);
                offset += list[x].Length;
            }
            return result;
        }

        static byte[] BuildStringBuffer(string str, int size)
        {
            System.Text.UnicodeEncoding encoding = new System.Text.UnicodeEncoding();
            byte[] strBytes = encoding.GetBytes(str);

            var result = new byte[(strBytes.Length > size) ? strBytes.Length : size];

            strBytes.CopyTo(result, 0);

            return result;
        }
    }
}
